#include <sys/select.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <signal.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/un.h>
#include <sys/stat.h>



#define HANDSHAKE 		0x00
#define FAIL 			0x01
#define PPD 			0x02
#define PRAID 			0x03
#define PFS 			0x04
#define GETSECTOR 		0x10
#define RTASECTOR 		0x11
#define WRITESECTOR 	0x12
#define WRITESECTOROK   0x13
#define HANDSHAKEOK     0x14
#define PFSCERRADO      0x15
#define PPDCERRADO      0x15

//PETICIONES DESDE LA CONSOLA
#define INFO 			0x20
#define CLEAN 			0x21
#define TRACE 			0x22
#define OK	 			0x23
#define CERRADO			0x24
#define TLECTURA		0x25
#define TESCRITURA		0x26

//RESPUESTAS CONSOLA
#define INFOOK 			0x30
#define CLEANOK			0x31
#define TRACEOK			0x32

#define PRUEBA			0x40

#define SINCRO			0x50
#define FINSINCRO		0x51

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
									MACROS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
#ifndef _MAXDESC_
		#define _MAXDESC_
		#define MAXDESC( maximo, nuevo ) maximo = ( (maximo > nuevo ) ? maximo : nuevo );
#endif

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
								ESTRUCTURAS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

typedef struct ST_CHS{
    int				cilindro;
    int            	cabeza;
    int            	sector;
} __attribute__ ((packed)) ST_CHS;

typedef struct ST_PPD{
	char	modo[9]; //LISTEN O CONNECT
	char	szIpRemoto[16];
	int		iPuertoRemoto;
	char	cAlgoritmo[6];
	int		iPuertoPPD;
	char	szIpPPD[16];
	int		iFlag; //Flag de habilitada o no la consola
	char	szIdPPD[40];
	int		iCilindro;
	int		iHead;
	int		iSector;
	float	iTiempoLectura;
	float	iTiempoEscritura;
	int		iRPM;
	int		iTiempoSalto;
	int		iSocketEscucha;
	int		iSocketRaid;
	int		iSocketConsola;
	char	szPath[255];
	char	*szPathConsola;
	char*	ArchivoEnDisco;
	int32_t	sectorActual;
	int		sectoresTotales;
	int		tiempoEntreSectores;
	int		cantElementosNStepScan;
	int 	cantSectoresEscritos;
	int		enSincro;
	size_t	filesize;
	ST_CHS  chsActual;
} __attribute__ ((packed)) ST_PPD;

typedef uint8_t ST_SECTOR[512];

typedef struct ST_NIPC{
    unsigned char     		ucType;
    int32_t            		lPayload;
//    char            		szPayload[600];
    int						sector;
    ST_SECTOR				buffer;
} __attribute__ ((packed)) ST_NIPC;

typedef struct ST_PEDIDOS{
    int						socketPedido;
    unsigned char			TipoPedido;
    int32_t					sector;
    ST_SECTOR          		buffer; //[600];
    int						realizado;
    int 					prioridad;
    ST_CHS					chs;
    struct ST_PEDIDOS		* sgte;
} __attribute__ ((packed)) ST_PEDIDOS;

typedef struct ST_PEDIDOS_INFO{
    int						socketPedido;
    int						TipoPedido;
    int32_t					sector;
    int						sectorProximo;
    int 					prioridad;
    ST_SECTOR            	buffer; //[600];
    int						subiendo;
    ST_CHS					chs;
    char					sectoresPendientes[1000000];
} __attribute__ ((packed)) ST_PEDIDOS_INFO;

typedef struct ST_PEDIDOS_NSTEP{
    int						IdLista;
    int						CantNodosSublistas;
    int						CantNodosRealizados;
    struct ST_PEDIDOS		* SubLista;
    struct ST_PEDIDOS_NSTEP	* sgte;
} __attribute__ ((packed)) ST_PEDIDOS_NSTEP;

typedef struct ST_RESPUESTA{
	unsigned char     		ucType;
    int						sector;
    ST_SECTOR				buffer;
} __attribute__ ((packed)) ST_RESPUESTA;

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
							VARIABLES GLOBALES
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

ST_PPD				stPPD;
ST_PEDIDOS			*listaPedidos=NULL;
ST_PEDIDOS_NSTEP 	*listaPedidosNStep;
ST_PEDIDOS			listaPedidosTrabajar, listaPedidosTrabajar2;
ST_SECTOR 			buffer;


/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
							FUNCIONES
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

int manejoPPDListen();
int manejoPPDConnect();
void exeConsola();
void consola(void *);
void ManejoColaPedidos(void *);
void finPPD(void);
void Pruebas();
